package cn.iocoder.yudao.module.erp.service.saleorder;

import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.erp.controller.admin.saleorder.vo.*;
import cn.iocoder.yudao.module.erp.convert.saleorder.ErpSaleOrderGoodsConvert;
import cn.iocoder.yudao.module.erp.dal.dataobject.saleorder.SaleOrderDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.saleorder.SaleOrderGoodsDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.stock.goods.GoodsDO;
import cn.iocoder.yudao.module.erp.dal.mysql.saleorder.SaleOrderGoodsMapper;
import cn.iocoder.yudao.module.erp.dal.mysql.saleorder.SaleOrderMapper;
import cn.iocoder.yudao.module.erp.dal.mysql.stock.goods.GoodsMapper;
import cn.iocoder.yudao.module.erp.dal.redis.no.ErpNoRedisDAO;
import cn.iocoder.yudao.module.erp.service.stock.goods.GoodsService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.List;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.SALEORDERGOODS_NOT_EXIST;
import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.SALE_ORDER_NOT_EXISTS;

/**
 * 报价订单 Service 实现类
 * 报价单和销售单是同一个表，调用的mapper是同一个，在mapper中做了区分
 * @author maxuxu
 */
@Service
@Validated
@Slf4j
public class QuoteOrderServiceImpl implements QuoteOrderService {

    @Resource
    private SaleOrderMapper saleOrderMapper;
    @Resource
    private SaleOrderGoodsMapper saleOrderGoodsMapper;

    @Resource
    private GoodsMapper goodsMapper;

//    @Resource
//    private SequenceService sequenceService;

    @Resource
    private ErpNoRedisDAO noRedisDAO;

    @Resource
    private SaleOrderService saleOrderService;

    @Resource
    private GoodsService goodsService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long createQuoteOrder(SaleOrderSaveReqVO createReqVO) {
        // 插入
        SaleOrderDO saleOrder = BeanUtils.toBean(createReqVO, SaleOrderDO.class);
        if (saleOrder.getBillNo() == null) {
//            saleOrder.setBillNo(sequenceService.nextSequence("BJ"));
            saleOrder.setBillNo(noRedisDAO.generate(ErpNoRedisDAO.SALE_ORDER_NO_PREFIX));
        }
        saleOrderMapper.insertQuoteOrder(saleOrder);
        // 校验子表
        List<SaleOrderGoodsDO> saleOrderGoodsList = validateSaleGoods(createReqVO.getItems());
        // 插入子表
        createSaleOrderGoodsList(saleOrder.getId(), saleOrderGoodsList);
        // 返回
        return saleOrder.getId();
    }
    private List<SaleOrderGoodsDO> validateSaleGoods(List<SaleOrderSaveReqVO.Item> items) {
        List<Long> itemIds = convertList(items, SaleOrderSaveReqVO.Item::getGoodsId);
        goodsService.validProductList(itemIds);
        return ErpSaleOrderGoodsConvert.INSTANCE.convertSaveVOList(items);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateQuoteOrder(SaleOrderSaveReqVO updateReqVO) {
        // 校验存在
        validateSaleOrderExists(updateReqVO.getId());
        // 更新
        SaleOrderDO updateObj = BeanUtils.toBean(updateReqVO, SaleOrderDO.class);
        // bean转换，type前端没传默认值是0，这里改成1报价单
        updateObj.setType(1);
        saleOrderMapper.updateById(updateObj);
        // 校验子表
        List<SaleOrderGoodsDO> saleOrderGoodsList = validateSaleGoods(updateReqVO.getItems());
        // 更新子表
        updateSaleOrderGoodsList(updateReqVO.getId(), saleOrderGoodsList);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteQuoteOrder(Long id) {
        // 校验存在
        validateSaleOrderExists(id);
        // 删除
        saleOrderMapper.deleteById(id);

        // 删除子表
        deleteSaleOrderGoodsByOrderId(id);
    }

    private void validateSaleOrderExists(Long id) {
        if (saleOrderMapper.selectById(id) == null) {
            throw exception(SALE_ORDER_NOT_EXISTS);
        }
    }

    @Override
    public SaleOrderDO getQuoteOrder(Long id) {
        return saleOrderMapper.selectById(id);
    }

    @Override
    public PageResult<SaleOrderDO> getQuoteOrderPage(SaleOrderPageReqVO pageReqVO) {
        return saleOrderMapper.selectQuoteOrderPage(pageReqVO);
    }

    /**
     * @param pageReqVO:
      * @return PageResult<SaleOrderDO>
     * @author Max-u-19
     * @description 分页查询订单，增加显示订单包含的物品和数量
     * @date 2024/1/23 13:11
     */

    @Override
    public PageResult<SaleOrderRespVO> getQuoteOrderWithGoodsPage(SaleOrderPageReqVO pageReqVO) {
        PageResult<SaleOrderDO> saleOrderDOPageResult = saleOrderMapper.selectQuoteOrderPage(pageReqVO);
        PageResult<SaleOrderRespVO> saleOrderRespVOPageResult = BeanUtils.toBean(saleOrderDOPageResult, SaleOrderRespVO.class);
        List<SaleOrderRespVO> saleOrderRespVOS = saleOrderRespVOPageResult.getList();
        saleOrderRespVOS.forEach(saleOrderVO ->{
            List<SaleOrderGoodsDO> saleOrderGoodsDOS = saleOrderGoodsMapper.selectListByOrderId(saleOrderVO.getId());
            saleOrderVO.setSaleOrderGoodsDOS(ErpSaleOrderGoodsConvert.INSTANCE.convertDOList(saleOrderGoodsDOS));
        });
        saleOrderRespVOPageResult.setList(saleOrderRespVOS);
        return saleOrderRespVOPageResult;
    }
    @Override
    public BigDecimal getSumQuoteOrderAmount(){
        List<SaleOrderDO> saleOrderDOS = saleOrderMapper.selectAmountTotal(1);
        return saleOrderDOS.stream().map((value) -> {
            if (value.getTotalAmount()!= null) {
                return value.getTotalAmount();
            }
            return BigDecimal.ZERO;
        }).reduce(BigDecimal.ZERO,BigDecimal::add);
    }

    @Override
    public SaleOrderImportRespVO importSaleOrderList(List<SaleOrderImportExcelVO> list, Boolean updateSupport, Long loginUserId) {
        return saleOrderService.importSaleOrderList(list, updateSupport, loginUserId);
    }
    // ==================== 子表（销售单和物品的链接表-多对多关系） ====================

    @Override
    public List<SaleOrderGoodsRespVO> getQuoteOrderGoodsListByOrderId(Long orderId) {
        List<SaleOrderGoodsDO> saleOrderGoodsDOS = saleOrderGoodsMapper.selectListByOrderId(orderId);
        if (CollectionUtils.isEmpty(saleOrderGoodsDOS)) {
            throw exception(SALEORDERGOODS_NOT_EXIST);
        }
        List<SaleOrderGoodsRespVO> saleOrderGoodsRespVOS = BeanUtils.toBean(saleOrderGoodsDOS, SaleOrderGoodsRespVO.class);
        saleOrderGoodsRespVOS.forEach((saleOrderGoodsRespVO) ->{
            GoodsDO goodsDO = goodsMapper.selectById(saleOrderGoodsRespVO.getGoodsId());
            saleOrderGoodsRespVO.setBrand(goodsDO.getBrand());
            saleOrderGoodsRespVO.setModels(goodsDO.getModels());
            saleOrderGoodsRespVO.setProBarCode(goodsDO.getProBarCode());
            saleOrderGoodsRespVO.setNameEn(goodsDO.getNameEn());
            saleOrderGoodsRespVO.setUnit(goodsDO.getUnit());
        });
        return saleOrderGoodsRespVOS;
    }

    private void createSaleOrderGoodsList(Long orderId, List<SaleOrderGoodsDO> list) {
        list.forEach(o -> o.setOrderId(orderId));
        saleOrderGoodsMapper.insertBatch(list);
    }

    private void updateSaleOrderGoodsList(Long orderId, List<SaleOrderGoodsDO> list) {
        deleteSaleOrderGoodsByOrderId(orderId);
        list.forEach(o -> o.setId(null).setUpdater(null).setUpdateTime(null)); // 解决更新情况下：1）id 冲突；2）updateTime 不更新
        createSaleOrderGoodsList(orderId, list);
    }

    private void deleteSaleOrderGoodsByOrderId(Long orderId) {
        saleOrderGoodsMapper.deleteByOrderId(orderId);
    }

}